package com.fpswork.datamodel.base;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import com.fpswork.Helper.DBProductUtil;
import com.fpswork.core.exception.exception.BusinessException;
import com.fpswork.core.exception.exception.SystemException;
import com.fpswork.datamodel.IPO;

public class BaseSql{

	@Autowired
    public JdbcTemplate jdbcTemplate;
	@Autowired
    protected SessionFactory sessionFactory;

    protected Session getCurrentSession(){
        return sessionFactory.getCurrentSession();
    }

    /**
     * 同Hibernate的SaveOrUpdate操作
     * @param table 类型：Object, Hibernate的Entity对象。
     * @return
     * @throws BusinessException
     **/
    public void saveOrUpdate(Object table) throws BusinessException {
        Session session= getCurrentSession();
        if(table instanceof IPO){
            if(session.contains(table)) {
                ((IPO) table).validatePO(((IPO) table).TYPE_UPDATE);
            }else{
                ((IPO) table).validatePO(((IPO) table).TYPE_INSERT);
            }
        }
        session.saveOrUpdate(table);
    }

    /**
     * 同Hibernate的SaveOrUpdate操作，批量SaveOrUpdate。
     * @param tableList 类型：List<Object> , Hibernate的Entity对象集合。
     * @return int 修改记录数量
     * @throws BusinessException
     **/
    public int saveOrUpdate(List tableList) throws BusinessException{
        int i=0;
        for(Object table:tableList){
            saveOrUpdate(table);
            i++;
        }
        return i;
    }

    /**
     * 将多条SQL查询结果取到<T> List<T>集合中。此处返回结果是Hibernate的处于持久态的Entity对象,而非普通JavaBean，开发者必须注意。
     * @param sql 类型：String, SQL语句。
     * @param c 类型：,Class<T>, 返回List泛型。
     * @return <T> List<T>，返回Hibernate的处于持久态的Entity对象集合。
     * @throws BusinessException
     */
    public  <T> List<T>  findBySql(String sql,Class<T> c) throws BusinessException{
        Session session= getCurrentSession();
        SQLQuery query = session.createSQLQuery(sql).addEntity("", c);
        return query.list();
    }

    /**
     * 将唯一的SQL查询结果取到<T>T对象中。此处返回结果是Hibernate的处于持久态的Entity对象,而非普通JavaBean，开发者必须注意。当sql语句返回多条记录时取第一条记录。
     * @param sql 类型：String, SQL语句。
     * @param c 类型：,Class<T>, 返回对象泛型。
     * @return <T>T，返回Hibernate的处于持久态的Entity对象。
     * @throws BusinessException
     */
    public  <T>T  findObjBySql(String sql,Class<T> c) throws BusinessException{
        if(sql==null||"".equals(sql)){
            throw new BusinessException("查询错误，查询语句("+sql+")不能为空！");
        }
        Session session= getCurrentSession();
        SQLQuery query = session.createSQLQuery(sql).addEntity("", c);
        return (T) query.uniqueResult();
    }

   
  

    /**
     * 将多条的查询结果取到List<Map>中
     * @param sql 类型：String, SQL语句。
     * @return List<Map>，返回结果集合List<Map>。
     * @throws BusinessException
     */
    public  List<Map> findBySql(String sql) throws BusinessException{
        Session session= getCurrentSession();
        SQLQuery query = session.createSQLQuery(sql);
        query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
        return query.list();
    }

    /**
     * 将唯一的查询结果取到Map中
     * @param sql 类型：String, SQL语句。
     * @return Map，返回查询的唯一一个结果集Map。
     * @throws BusinessException
     **/
    public  Map findObjBySql(String sql) throws BusinessException{
        Session session= getCurrentSession();
        SQLQuery query = session.createSQLQuery(sql);
        query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
        return (Map) query.uniqueResult();
    }

    /**
     * 同Hibernate的Save操作
     * @param table 类型：Object, Hibernate的Entity对象。
     * @return
     * @throws BusinessException
     **/
    public  void save(Object table) throws BusinessException{
        Session session= getCurrentSession();
        if(table instanceof IPO){
            ((IPO) table).validatePO(((IPO) table).TYPE_INSERT);
        }
        session.save(table);
    }

    /**
     * 同Hibernate的Save操作，批量保存。
     * @param tableList 类型：List<Object> , Hibernate的Entity对象集合。
     * @return int 保存记录数量
     * @throws BusinessException
     **/
    public int save(List  tableList  ) throws BusinessException{
        int i=0;
        for(Object table:tableList){
            save(table);
            i++;
        }
        return i;
    }

    /**
     * 同Hibernate的Update操作
     * @param table 类型：Object, Hibernate的Entity对象。
     * @return
     * @throws BusinessException
     **/
    public  void update(Object table) throws BusinessException{
        Session session=getCurrentSession();
        if(table instanceof IPO){
            ((IPO) table).validatePO(((IPO) table).TYPE_UPDATE);
        }
        session.update(table);
    }

    /**
     * 同Hibernate的Update操作，批量Update。
     * @param tableList 类型：List<? extends Serializable> , Hibernate的Entity对象集合。
     * @return int 修改记录数量
     * @throws BusinessException
     **/
    public  int update(List tableList ) throws BusinessException{
        int i=0;
        for(Object table:tableList){
            update(table);
            i++;
        }
        return i;
    }

    /**
     * 同Hibernate的Delete操作
     * @param table 类型：Object, Hibernate的Entity对象。
     * @return
     * @throws BusinessException
     **/
    public  void delete(Object table) throws BusinessException{
        Session session=  getCurrentSession();
        if(table instanceof IPO){
            ((IPO) table).validatePO(((IPO) table).TYPE_DELETE);
        }
        session.delete(table);
    }

    /**
     * 同Hibernate的Delete操作，批量Delete。
     * @param tableList 类型：List<Object> , Hibernate的Entity对象集合。
     * @return int 删除记录数量
     * @throws BusinessException
     **/
    public  int delete(List tableList) throws BusinessException{
        Session session=  getCurrentSession();
        int i=0;
        for(Object table:tableList){
            if(table instanceof IPO){
                ((IPO) table).validatePO(((IPO) table).TYPE_DELETE);
            }
            session.delete(table);
            i++;
        }
        return i;
    }

    /**
     * 同Hibernate的Get操作。
     * @param table 类型：Class ,返回数据类型。
     * @param key 类型：Serializable 主键。
     * @return   Hibernate的Entity对象
     * @throws BusinessException
     **/
    public   <T> T get(Class<T> table,Serializable key) throws BusinessException{
        Session session= getCurrentSession();
        return (T) session.get(table, key);
    }

    /**
     * 同Hibernate的Get操作。
     * @param table 类型：Class ,返回数据类型。
     * @param key 类型：Serializable 主键。
     * @return   Hibernate的Entity对象
     * @throws BusinessException
     **/
    public <T> T load( Class<T> table, Serializable key) throws BusinessException{
        Session session= getCurrentSession();
        return (T) session.load(table, key);
    }

    /**
     * 同Hibernate的Flush操作。
     * @return
     * @throws BusinessException
     **/
    public void flush( ) throws BusinessException{
        Session session= getCurrentSession();
        session.flush();
    }

    /**
     * 同Hibernate的Merge操作。
     * @return
     * @throws BusinessException
     **/
    public void merge(Object table) throws BusinessException{
        Session session= getCurrentSession();
        session.merge(table);
    }

    /**
     * 同Hibernate的Refresh操作。
     * @return
     * @throws BusinessException
     **/
    public void refresh(Object table) throws BusinessException{
        Session session= getCurrentSession();
        session.refresh(table);
    }

	@SuppressWarnings({ "rawtypes", "static-access" })
	public List queryForList(String sql,Object args[], final int pagecount, final int curpage) {
		String dbProductName = DBProductUtil.getInstance(jdbcTemplate).getProductName();
		
		if (pagecount == 0 || curpage == 0) {
			return null;
		} else if (curpage == 1) {
			if("Oracle".equals(dbProductName) ){
				sql = "select * from ( " + sql + ") where rownum <= " + pagecount;
			}else if("MySQL".equals(dbProductName)){
				sql = sql +" limit 0," + pagecount;
			}
		} else if (curpage > 1) {
			if("Oracle".equals(dbProductName) ){
				sql = "select * from (select spt.*,rownum rn from ( " + sql
						+ ")spt  where rownum <= " + pagecount * curpage
						+ ") where rn > " + pagecount * (curpage - 1);
			}else if("MySQL".equals(dbProductName)){
				sql =  sql+ " limit " + (pagecount * (curpage-1) )+ "," + pagecount;
			}
		}
		try {
			if(args != null && args.length > 0){
				return (List) jdbcTemplate.queryForList(sql, args);
			}
			else{
				return (List) jdbcTemplate.queryForList(sql);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new SystemException();
		}
	}

	
	@SuppressWarnings({ "rawtypes", "unchecked", "static-access" })
	public List<Object> queryForList(String sql,Object args[], final int pagecount, final int curpage,Class c) {
		String dbProductName = DBProductUtil.getInstance(jdbcTemplate).getProductName();
		if (pagecount == 0 || curpage == 0) {
			return null;
		} else if (curpage == 1) {
			if("Oracle".equals(dbProductName) ){
				sql = "select * from ( " + sql + ") where rownum <= " + pagecount;
			}else if("MySQL".equals(dbProductName)){
				sql = sql +" limit 0," + pagecount;
			}
		} else if (curpage > 1) {
			if("Oracle".equals(dbProductName) ){
				sql = "select * from (select spt.*,rownum rn from ( " + sql
						+ ")spt  where rownum <= " + pagecount * curpage
						+ ") where rn > " + pagecount * (curpage - 1);
			}else if("MySQL".equals(dbProductName)){
				sql =  sql+ " limit " + (pagecount * (curpage-1) )+ "," + pagecount;
			}
		}
		try {
			if(args != null && args.length > 0){
				return (List) jdbcTemplate.query(sql, args,new BeanPropertyRowMapper(c));
			}
			else{
				return (List) jdbcTemplate.query(sql,new BeanPropertyRowMapper(c));
			} 
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new SystemException();
		}
	}

	
}
